
//////////// MODE FUNCTIONS INITIALIZATION & CHANGE ////////////


void killAllSpots(){ 
  for(int i=0; i<NBSPOT; i++) spotArray[i].alive = false;
}

void modeChange(int modeNumber) {
  // first, kill all the spots that are alive:
  killAllSpots();
  
  // then, reset parameters and make spots alives as desired: 
switch(modeNumber) {
  
 case 0: // bouncing one spot: 
     IO.clearLCD();
     IO.displayLineLCD(" SIMPLE      ",1);
     IO.displayLineLCD(" BOUNCING    ",2);
     simpleBouncingOnly(0); // load default simple bouncing parameters and activate spot (in spot array index 0)
     spotArray[0].touchSoundMode=SUPER_BASS;
     spotArray[0].collisionSoundMode=SUPER_BASS;
 break;
  
 case 1: // following one spot: 
      IO.clearLCD();
      IO.displayLineLCD("CONTOUR      ",1);
      IO.displayLineLCD("FOLLOWING    ",2);
     contourFollowingOnly(0); // load default contour following parameters and activate spot at array spot index 0
     // modify some things if we want: 
     spotArray[0].speedContourFollowing = 0.75;
     spotArray[0].touchSoundMode=FREE_BASS;
     spotArray[0].collisionSoundMode=FREE_BASS;
     spotArray[0].countourSoundMode=SUPER_BASS;
   break;
   
 case 2: //following one spot + bouncing one spot: 
      IO.clearLCD();
      IO.displayLineLCD("BOUNCE +     ",1);
      IO.displayLineLCD("FOLLOWING    ",2);
      // contour following: 
      contourFollowingOnly(0); // load contour following parameters and activate spot at array spot index 0
      spotArray[0].speedContourFollowing = 0.75;
      spotArray[0].touchSoundMode=SUPER_BASS;
     spotArray[0].collisionSoundMode=SUPER_BASS;
     spotArray[0].countourSoundMode=SUPER_BASS;
      // bouncing: 
      simpleBouncingOnly(1); // load default simple bouncing parameters and activate spot (in spot array index 1)
      spotArray[1].touchSoundMode=FREE_BASS;
     spotArray[1].collisionSoundMode=FREE_BASS;
 break;
 
case 3: // one newtonian spot with central attraction
   IO.clearLCD();
   IO.displayLineLCD(" CENTRAL     ",1);
   IO.displayLineLCD(" INTERACTION ",2);
    simpleBouncingCentralForce(0);
    spotArray[0].touchSoundMode=FREE_BASS;
    spotArray[0].collisionSoundMode=FREE_BASS;
     simpleBouncingCentralForce(1);
    spotArray[1].touchSoundMode=FREE_BASS;
    spotArray[1].collisionSoundMode=FREE_BASS;
     simpleBouncingCentralForce(2);
    spotArray[2].touchSoundMode=FREE_BASS;
    spotArray[2].collisionSoundMode=FREE_BASS;
   break;
  /* 
 case 3: // one newtonian spot with central attraction
   IO.clearLCD();
   IO.displayLineLCD(" NEWTONIAN   ",1);
   IO.displayLineLCD(" INTERACTION ",2);
   newtonianBouncingOnly(0);
   // set central attraction only: 
   spotArray[0].bouncingForceMode=false; 
   spotArray[0].bouncingSpecularMode=false;
   spotArray[0].centralForceMode=true; 
   spotArray[0].parallelForceMode=false; 
   spotArray[0].particleInteractionMode=false; 
   spotArray[0].visForceMode=false; 
   spotArray[0].mass=10;//0.3;//+i*0.2;
    // sound: 
    spotArray[0].touchSoundMode=FREE_BASS;
    spotArray[0].collisionSoundMode=FREE_BASS;
   break;
   */
   
 case 4: 
   IO.clearLCD();
   IO.displayLineLCD(" FAST        ",1);
   IO.displayLineLCD(" BOUNCING    ",2);
   fastBouncingOnly(0);
    spotArray[0].touchSoundMode=SUPER_BASS;
    spotArray[0].collisionSoundMode=SUPER_BASS;
   break;  
   
 case 5: // CONTOUR FOLLOWING AVEC MONOCYLE...
      IO.clearLCD();
      IO.displayLineLCD("CONTOUR      ",1);
      IO.displayLineLCD("MONOCYCLE!   ",2);
     contourFollowingOnly(0);
     spotArray[0].displayMonocycle=true;
     spotArray[0].speedContourFollowing = 1.1;
     //spotArray[0].R_cm_REF=1;
     spotArray[0].setAperSaccade(21);
    // spotArray[0].setRadiusSaccade(1);  
     spotArray[0].RadiusCorrectionMode=RADIUS_FIXED;//
     
       contourFollowingOnly(1);
     spotArray[1].speedContourFollowing = 1.60;
     spotArray[1].displayMonocycle=true;
     //spotArray[0].R_cm_REF=1;
     spotArray[1].setAperSaccade(21); 
    //  spotArray[1].setRadiusSaccade(2); 
     spotArray[1].RadiusCorrectionMode=RADIUS_FIXED;//
   break;
   
 case 6: // SLP DEMO with depth sensing (letters don't move)
      IO.clearLCD();
      IO.displayLineLCD("DEPTH SENSING",1);
      IO.displayLineLCD("TEXT         ",2);
      lettersSLP(0, 'S'); // rem: position will depend on the index (this is a hack...)
      lettersSLP(1, 'L');
      lettersSLP(2, 'P');
   break;
   
  case 7: // contour following with FIXED threshold (set with potentiometer), useful for COUNTOUR LINES DETECTION ("depth contour followin")
   IO.clearLCD();
   IO.displayLineLCD(" FOLLOWING   ",1);
   IO.displayLineLCD(" FIXED THRESH",2);
   contourFollowingOnly(0);
   spotArray[0].thresholding_Mode=DEPTH_THRESHOLD; //AUTO_THRESHOLD
   //spotArray[0].setRadiusSaccade(2); 
   spotArray[0].setAperSaccade(35); // larger saccade radius for depth discrimination
   break;
   
 case 8: // SNELL LAW
   IO.clearLCD();
   IO.displayLineLCD(" SNELL       ",1);
   IO.displayLineLCD("  LAW        ",2);
   snellLawOnly(0);
   //spotArray[0].setRadiusSaccade(2); 
   break;
 
  case 9: 
     IO.clearLCD();
    IO.displayLineLCD(" STAND BY    ",1);
    IO.displayLineLCD("(POT CONTROL)",2);
    standByCenter(0);
   break;
   
   /*
    case 9: // TRACKING (REM: DEPTH ANNOTATION ON/OFF with Serial command a/A)
   IO.clearLCD();
   IO.displayLineLCD(" MARKERLESS  ",1);
   IO.displayLineLCD("  TRACKING   ",2);
   markerlessTrackingOnly(1);
   spotArray[0].setRadiusSaccade(1.0); 
   // spotArray[0].setAperSaccade(30);
   break;
   */
   
   default:
   // don't change anything
   break;
}
}


void contourFollowingOnly(int i) {
  // then, initialize the spot we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(2000, 2000, 45 , 20, i); 
                
                spotArray[i].behaviourMode = COUNTOUR_FOLLOWING;
                spotArray[i].alive = true;
                
                // Trajectory shape:
	         spotArray[i].createCircularSaccade(20);//MAX_SACCADE_SAMPLES); 	
                spotArray[i].setAperSaccade(25); 

		spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//, DEPTH_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode= RADIUS_FIXED ;//RADIUS_ADJUST;// 
                // NOTE: in contour following, it is better sometimes not to adjust the radius (the reason is that if the spot enters a dark zone, it will shrink, because 
                // the system will interpret this as the target being very far...
                
                spotArray[i].borderMode=NORMAL_REFLEXION;
                                
		//spotArray[i].vx = 20; 
		//spotArray[i].vy = 20;
		spotArray[i].speedContourFollowing = 0.5;//0.9; // controls the speed of contour following (proportion of radius)
midiAllSoundOff();
}

void simpleBouncingOnly(int i){
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(1000, 1000, 40+8*i , 25, i); 
		
                spotArray[i].behaviourMode = SIMPLE_BOUNCING;
                spotArray[i].alive = true;

                  // Trajectory shape:
	         spotArray[i].createCircularSaccade(20); 	
                spotArray[i].setAperSaccade(28); 
                
                spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode= RADIUS_FIXED; //RADIUS_ADJUST; //
                
                spotArray[i].borderMode=NORMAL_REFLEXION;

		spotArray[i].vx = 20+8*i; 
		spotArray[i].vy = 20-8*i;
		spotArray[i].alive = true;
midiAllSoundOff();
}

void simpleBouncingCentralForce(int i){
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(1000, 1000, 40+8*i , 25, i); 
		
                spotArray[i].behaviourMode = SIMPLE_BOUNCING_CENTRAL;
                spotArray[i].alive = true;

                  // Trajectory shape:
	         spotArray[i].createCircularSaccade(20); 	
                spotArray[i].setAperSaccade(28); 
                
                spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode= RADIUS_FIXED; //RADIUS_ADJUST; //
                
                spotArray[i].borderMode=NORMAL_REFLEXION;

		spotArray[i].vx = 15+8*i; 
		spotArray[i].vy = 15-8*i;
		spotArray[i].alive = true;
midiAllSoundOff();
}

void lettersSLP(int i, char letter) { // show SLP with depth sensing for EACH letter
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(1000, 1000, 30+8*i , 20, i); 
                spotArray[i].behaviourMode = DEPTH_LETTERS;
                spotArray[i].alive = true;
                
                  // Trajectory shapes (see below):
	         //spotArray[i].createCircularSaccade(MAX_SACCADE_SAMPLES); 	

                // initial position: 
                float mirrorSpanX=spotArray[i].xMax-spotArray[i].xMin;
                float mirrorSpanY=spotArray[i].yMax-spotArray[i].yMin;
                spotArray[i].updatePosition(spotArray[i].xMin+1.0*(i+1)*mirrorSpanX/(NBSPOT+1), CENTER_AD_MIRROR_Y);
                
                spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                
                // size of the saccade, and radius correction mode:
                spotArray[i].RadiusCorrectionMode= RADIUS_ADJUST; // RADIUS_FIXED; 
                 spotArray[i].setAperSaccade(100); 
                //spotArray[i].setRadiusSaccade(10); // in cm
                
                spotArray[i].borderMode=NORMAL_REFLEXION;
		
    // load the proper data on the saccade: 
    spotArray[i].set_circularSaccadeFromChar(letter);
     
     // spotArray[0].set_circularSaccadeFromChar('S');
     // spotArray[1].set_circularSaccadeFromChar('L');
     // spotArray[2].set_circularSaccadeFromChar('P');
      
     midiAllSoundOff();
}

void newtonianBouncingOnly(int i) {
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(2100+i*500, 1500+i*500, 30+8*i , 20, i); 
                
                spotArray[i].behaviourMode = NEWTON_DYNAMICS;
                spotArray[i].alive = true;
                
                  // Trajectory shape:
	         spotArray[i].createCircularSaccade(20); 	
                spotArray[i].setAperSaccade(40); 
                
		spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode= RADIUS_ADJUST; // RADIUS_FIXED; //

                spotArray[i].borderMode=NORMAL_REFLEXION;
                   
		// UpdateSpeed must be used when setting speed in NETWON_DYNAMICS mode, right after updatePosition (or Init of course).  
		spotArray[i].updatePosition(random(1000)+1500, random(1000)+1500); 
		spotArray[i].updateSpeed(-15,10);

		spotArray[i].bouncingForceMode=false; // default true
		spotArray[i].bouncingSpecularMode=false;
		spotArray[i].centralForceMode=false; // default mode is CENTRAL force active
		spotArray[i].parallelForceMode=true; // default mode is parallel force inactive
		spotArray[i].particleInteractionMode=false;// default mode 
		spotArray[i].visForceMode=false; // default mode false
		spotArray[i].mass=0.3;//+i*0.2;

	// Massive spot: 
	//spotArray[0].updatePosition( CENTER_AD_MIRROR_X,  CENTER_AD_MIRROR_Y); 
	//spotArray[0].updateSpeed(-20, 10); 
	//spotArray[0].mass=0.5;
	//spotArray[0].charge=1; // it will attract harder if charge>1 (the others have charge=1)

midiAllSoundOff();
}

void standByCenter(int i) {
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(1000, 1000, 30+8*i , 20, i); 
                spotArray[i].behaviourMode = STAND_CENTER;
                spotArray[i].alive = true;
                
                  // Trajectory shape:
	         spotArray[i].createCircularSaccade(MAX_SACCADE_SAMPLES); 	
                spotArray[i].setAperSaccade(80); 
                
                spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode= RADIUS_ADJUST; // RADIUS_FIXED; //
		
midiAllSoundOff();
}

void markerlessTrackingOnly(int i) {
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(1000, 1000, 30+8*i , 20, i); 
                spotArray[i].behaviourMode = TRACKING;
                spotArray[i].alive = true;
                
                  // Trajectory shape:
	         spotArray[i].createCircularSaccade(30); 	
                spotArray[i].setAperSaccade(20); 
                
                spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode=RADIUS_FIXED; // RADIUS_ADJUST; // 
                
                spotArray[i].borderMode=NORMAL_REFLEXION;
midiAllSoundOff();
}


void fastBouncingOnly(int i){
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(1000, 1000, 35+8*i , 20, i); 
                
                spotArray[i].behaviourMode = FAST_BOUNCING;
                spotArray[i].alive = true;
                
                  // Trajectory shape:
	         spotArray[i].createCircularSaccade(20); 	
                spotArray[i].setAperSaccade(40); 
                
                spotArray[i].thresholding_Mode=AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode= RADIUS_FIXED; //RADIUS_ADJUST; 
                
                spotArray[i].borderMode=RESET_POSITION;//NORMAL_REFLEXION;

		spotArray[i].vx = 10; 
		spotArray[i].vy = 3;

midiAllSoundOff();
}

void snellLawOnly(int i){
  // then, initialize the spots we need, with the right modes and parameters: 
		//Init parameters: (int posX, int posY, int saccadeRadius, int numSample, int id)
		//spotArray[i].Init(1000, 1000, 45, 35, i);
                
                spotArray[i].behaviourMode = SNELL_LAW;
                spotArray[i].alive = true;

                  // Trajectory shape:
	         spotArray[i].createCircularSaccade(MAX_SACCADE_SAMPLES); 	
                spotArray[i].setAperSaccade(35); 

		spotArray[i].thresholding_Mode=FIXED_THRESHOLD; //AUTO_THRESHOLD;//FIXED_THRESHOLD; //AUTO_THRESHOLD
                spotArray[i].PowerCorrectionMode=POWER_ADJUST; // POWER_FIXED;
                spotArray[i].RadiusCorrectionMode= RADIUS_FIXED; //
		//spotArray[i].error_angle = -0.25;
		
		// behaviour at the borders:
		spotArray[i].borderMode =  RESET_POSITION;// RETRO_REFLEXION // NORMAL_REFLEXION;

		spotArray[i].Az_Default=550;   spotArray[i].El_Default=CENTER_AD_MIRROR_Y; // special position where the spot appear after it touches the wall (when in RETRO_REFLEXION mode)
		spotArray[i].borderDamping=false;
		spotArray[i].showLimits=true;
		spotArray[i].showGreenFlash=false;

		spotArray[i].firstTimeStartRefraction=true; 
		spotArray[i].initVx = spotArray[i].Aper_DA;//10+8*i; 
		spotArray[i].initVy = 0;//-8*i;
                spotArray[i].vx = spotArray[i].initVx;//10+8*i; 
		spotArray[i].vy = 0;//-8*i;
		
                spotArray[i].fixed_Threshold_Volts=1.5;

		//int xMax, yMax, xMin, yMin; //borde 

midiAllSoundOff();
}




